package com.example.limit.rule;

import com.example.limit.entity.PurchaseRule;
import com.example.limit.service.RedisCounterService;
import org.jeasy.rules.api.Rule;
import org.jeasy.rules.support.RuleDefinition;
import org.jeasy.rules.support.composite.CompositeRule;
import org.jeasy.rules.support.composite.UnitRuleGroup;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 组合规则构建器 - 支持规则组的复杂逻辑组合
 */
public class CompositeRuleBuilder {
    
    /**
     * 构建AND逻辑的组合规则
     */
    public static CompositeRule buildAndRuleGroup(String name, List<Rule> rules) {
        UnitRuleGroup andGroup = new UnitRuleGroup(name);
        rules.forEach(andGroup::addRule);
        return andGroup;
    }
    
    /**
     * 构建OR逻辑的组合规则  
     */
    public static CompositeRule buildOrRuleGroup(String name, List<Rule> rules) {
        // 使用自定义的OR规则组
        OrRuleGroup orGroup = new OrRuleGroup(name);
        rules.forEach(orGroup::addRule);
        return orGroup;
    }
    
    /**
     * 根据数据库规则构建组合规则
     */
    public static CompositeRule buildFromDbRules(String groupName, List<PurchaseRule> dbRules, 
                                                RedisCounterService counterService) {
        List<Rule> rules = dbRules.stream()
            .map(dbRule -> new RedisAwareRule(dbRule, counterService))
            .collect(Collectors.toList());
            
        // 假设第一个规则的groupLogic代表整个组的逻辑
        Integer groupLogic = dbRules.get(0).getGroupLogic();
        
        if (groupLogic != null && groupLogic == 2) { // OR逻辑
            return buildOrRuleGroup(groupName, rules);
        } else { // 默认AND逻辑
            return buildAndRuleGroup(groupName, rules);
        }
    }
    
    /**
     * 自定义OR规则组
     */
    public static class OrRuleGroup extends CompositeRule {
        private final List<Rule> rules = new ArrayList<>();
        
        public OrRuleGroup(String name) {
            super(name);
        }
        
        public void addRule(Rule rule) {
            rules.add(rule);
        }
        
        @Override
        public boolean evaluate(org.jeasy.rules.api.Facts facts) {
            if (!rules.isEmpty()) {
                for (Rule rule : rules) {
                    if (rule.evaluate(facts)) {
                        return true; // OR逻辑：任意规则通过即可
                    }
                }
                return false; // 所有规则都不通过
            }
            // 空规则组返回true
            return true;
        }
        
        @Override
        public void execute(org.jeasy.rules.api.Facts facts) throws Exception {
            for (Rule rule : rules) {
                if (rule.evaluate(facts)) {
                    rule.execute(facts);
                    break; // OR逻辑：只执行第一个通过的规则
                }
            }
        }
        
        public List<Rule> getRules() {
            return new ArrayList<>(rules);
        }
    }
    
    /**
     * 条件规则组 - 根据条件动态选择规则
     */
    public static class ConditionalRuleGroup extends CompositeRule {
        private final String conditionExpression;
        private final List<Rule> rules = new ArrayList<>();
        
        public ConditionalRuleGroup(String name, String conditionExpression) {
            super(name);
            this.conditionExpression = conditionExpression;
        }
        
        public void addRule(Rule rule) {
            rules.add(rule);
        }
        
        @Override
        public boolean evaluate(org.jeasy.rules.api.Facts facts) {
            // 这里可以集成MVEL表达式引擎来评估条件
            // 简化实现：总是返回true
            return true;
        }
        
        @Override
        public void execute(org.jeasy.rules.api.Facts facts) throws Exception {
            // 根据条件选择要执行的规则
            List<Rule> rulesToExecute = selectRulesByCondition(facts);
            
            for (Rule rule : rulesToExecute) {
                if (rule.evaluate(facts)) {
                    rule.execute(facts);
                }
            }
        }
        
        private List<Rule> selectRulesByCondition(org.jeasy.rules.api.Facts facts) {
            // 根据条件表达式选择规则
            // 简化实现：返回所有规则
            return new ArrayList<>(rules);
        }
        
        public List<Rule> getRules() {
            return new ArrayList<>(rules);
        }
    }
}